from rest_framework import viewsets, status
from rest_framework.decorators import action, api_view, permission_classes
from rest_framework.response import Response
from rest_framework.permissions import IsAuthenticated, AllowAny
from django.utils import timezone
from django.db.models import Q, Count
from datetime import datetime, timedelta, date
import logging
from ..models import Event, Calendar
from ..serializers import EventSerializer, CalendarSerializer
from ..services.ai_services import ScheduleAIService
from ..services.conflict_service import ConflictService

logger = logging.getLogger('apps')


class BaseResponse:
    """基础响应类"""

    @staticmethod
    def success(data=None, message="操作成功"):
        return Response({
            "status": "success",
            "message": message,
            "data": data
        })

    @staticmethod
    def error(message="操作失败", status=status.HTTP_400_BAD_REQUEST):
        return Response({
            "status": "error",
            "message": message
        }, status=status)


class EventViewSet(viewsets.ModelViewSet):
    """日程视图集"""
    serializer_class = EventSerializer
    permission_classes = [IsAuthenticated]

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.ai_service = ScheduleAIService()
        self.conflict_service = ConflictService()

    def get_queryset(self):
        """获取查询集，支持日期和日期范围过滤"""
        queryset = Event.objects.filter(user=self.request.user)

        # 获取请求参数
        date = self.request.query_params.get('date')
        start_date = self.request.query_params.get('start_date')
        end_date = self.request.query_params.get('end_date')

        # 按日期过滤
        if date:
            queryset = queryset.filter(date=date)

        # 按日期范围过滤
        if start_date and end_date:
            queryset = queryset.filter(date__gte=start_date, date__lte=end_date)
        elif start_date:
            queryset = queryset.filter(date__gte=start_date)
        elif end_date:
            queryset = queryset.filter(date__lte=end_date)

        # 获取排序参数
        ordering = self.request.query_params.get('ordering', 'date,start_time')
        order_fields = ordering.split(',')

        return queryset.order_by(*order_fields)

    def perform_create(self, serializer):
        """创建时自动关联用户"""
        try:
            serializer.save(
                user=self.request.user,
                creator_id=self.request.user.id
            )
        except Exception as e:
            raise ValueError(f"创建日程失败: {str(e)}")

    def create(self, request, *args, **kwargs):
        """创建日程"""
        try:
            serializer = self.get_serializer(data=request.data)
            serializer.is_valid(raise_exception=True)

            # 直接使用当前登录用户创建日程
            event = serializer.save(
                user=request.user,
                creator_id=request.user.id
            )

            # 自动将创建者添加为相关用户
            event.related_users.add(request.user)

            return BaseResponse.success(serializer.data, "日程创建成功")
        except Exception as e:
            return BaseResponse.error(f"创建失败: {str(e)}")

    def update(self, request, *args, **kwargs):
        """更新日程"""
        try:
            # 移除 participants 字段
            data = request.data.copy()
            if 'participants' in data:
                del data['participants']

            partial = kwargs.pop('partial', False)
            instance = self.get_object()
            serializer = self.get_serializer(
                instance,
                data=data,
                partial=partial
            )
            serializer.is_valid(raise_exception=True)
            self.perform_update(serializer)

            # 更新相关用户
            related_users = request.data.get('related_users')
            if related_users is not None:
                instance.related_users.clear()
                instance.related_users.add(*related_users)

            return BaseResponse.success(serializer.data, "日程更新成功")
        except Exception as e:
            return BaseResponse.error(f"更新失败: {str(e)}")

    @action(detail=False, methods=['get'])
    def today(self, request):
        """获取今日日程"""
        try:
            today = timezone.now().date()
            events = self.get_queryset().filter(date=today)

            # 统计信息
            total_count = events.count()
            completed_count = events.filter(status='completed').count()

            # 按时间段分组
            data = {
                'date': today,
                'total': total_count,
                'completed': completed_count,
                'morning': self.get_serializer(
                    events.filter(period='morning'),
                    many=True
                ).data,
                'afternoon': self.get_serializer(
                    events.filter(period='afternoon'),
                    many=True
                ).data
            }
            return BaseResponse.success(data)
        except Exception as e:
            return BaseResponse.error(f"获取今日日程失败: {str(e)}")

    @action(detail=False, methods=['get'])
    def upcoming(self, request):
        """获取未来日程"""
        try:
            days = int(request.query_params.get('days', 7))
            today = timezone.now().date()
            end_date = today + timedelta(days=days)

            events = self.get_queryset().filter(
                date__gte=today,
                date__lte=end_date,
                status='pending'  # 只获取未完成的
            )

            # 按日期分组
            result = {}
            for event in events:
                date_str = event.date.strftime('%Y-%m-%d')
                if date_str not in result:
                    result[date_str] = []
                result[date_str].append(self.get_serializer(event).data)

            return BaseResponse.success(result)
        except Exception as e:
            return BaseResponse.error(f"获取未来日程失败: {str(e)}")

    @action(detail=True, methods=['post'])
    def complete(self, request, pk=None):
        """完成或取消完成日程"""
        try:
            event = self.get_object()
            # 修改这里，优先使用status字段，如果没有则使用isCompleted字段
            status = request.data.get('status')
            if status:
                event.status = status
            else:
                is_completed = request.data.get('isCompleted', False)
                event.status = 'completed' if is_completed else 'pending'

            # 直接保存，不使用update_fields参数
            event.save()

            # 确保数据库中的状态已更新，重新获取对象
            event.refresh_from_db()

            # 记录日志
            print(f"Event {pk} status updated to: {event.status}")

            return BaseResponse.success(self.get_serializer(event).data, "日程状态已更新")
        except Exception as e:
            print(f"Error updating event status: {str(e)}")
            return BaseResponse.error(f"操作失败: {str(e)}")

    @action(detail=False, methods=['get'])
    def search(self, request):
        """搜索日程"""
        try:
            keyword = request.query_params.get('keyword', '').strip()
            if not keyword:
                return BaseResponse.error("请提供搜索关键词")

            # 构建查询条件
            query = Q(title__icontains=keyword) | Q(description__icontains=keyword)

            # 状态过滤
            status = request.query_params.get('status')
            if status:
                query &= Q(status=status)

            events = self.get_queryset().filter(query)
            return BaseResponse.success(self.get_serializer(events, many=True).data)
        except Exception as e:
            return BaseResponse.error(f"搜索失败: {str(e)}")

    @action(detail=False, methods=['get'], url_path='date-range')
    def date_range(self, request):
        """获取日期范围内的日程"""
        try:
            start_date = request.query_params.get('start_date')
            end_date = request.query_params.get('end_date')

            if not start_date or not end_date:
                return BaseResponse.error("请提供开始日期和结束日期")

            # 使用get_queryset方法自动处理日期范围过滤
            events = self.get_queryset()

            # 按日期分组返回
            result = {}
            for event in events:
                date_str = event.date.strftime('%Y-%m-%d')
                if date_str not in result:
                    result[date_str] = []
                result[date_str].append(self.get_serializer(event).data)

            return BaseResponse.success({
                'date_range': {
                    'start': start_date,
                    'end': end_date
                },
                'events_by_date': result,
                'total_count': sum(len(events) for events in result.values())
            })
        except Exception as e:
            return BaseResponse.error(f"获取日期范围内日程失败: {str(e)}")

    @action(detail=False, methods=['post'], url_path='analyze-and-create')
    def analyze_and_create(self, request):
        """分析内容并创建日程"""
        try:
            content = request.data.get('content')
            title = request.data.get('title')  # 获取标题
            auto_create = request.data.get('autoCreate', False)

            if not content:
                return BaseResponse.error("请提供需要分析的内容")

            # 分析内容
            analysis = self.ai_service.analyze_content(content)
            if not analysis:
                return BaseResponse.error("内容分析失败")

            # 生成日程
            schedule = self.ai_service.generate_schedule(analysis)
            if not schedule:
                return BaseResponse.error("日程生成失败")

            # 创建日程（可选）
            if auto_create:
                schedule_data = {
                    'title': title,  # 使用前端传来的标题
                    'description': schedule['description'],
                    'date': schedule['date'],
                    'start_time': schedule['start_time'],
                    'end_time': schedule['end_time'],
                    'location': schedule.get('location', ''),
                    'importance': schedule['importance'],
                    'ai_suggestions': schedule['ai_suggestions']
                }

                serializer = self.get_serializer(data=schedule_data)
                if serializer.is_valid():
                    self.perform_create(serializer)
                    schedule['created_event'] = serializer.data
                else:
                    return BaseResponse.error("日程创建失败")

            return BaseResponse.success(schedule)
        except Exception as e:
            return BaseResponse.error(f"处理失败: {str(e)}")

    @action(detail=False, methods=['post'], url_path='suggest')
    def suggest(self, request):
        """获取日程建议"""
        try:
            title = request.data.get('title')
            description = request.data.get('description', '')

            if not title:
                return BaseResponse.error("请提供日程标题")

            suggestions = self.ai_service.get_schedule_suggestions(title, description)
            if not suggestions:
                return BaseResponse.error("无法生成建议")

            return BaseResponse.success(suggestions)
        except Exception as e:
            return BaseResponse.error(f"获取建议失败: {str(e)}")

    @action(detail=False, methods=['post'], url_path='best-time')
    def best_time(self, request):
        """获取最佳时间建议"""
        try:
            date_str = request.data.get('date')
            duration = request.data.get('duration', 60)

            if not date_str:
                return BaseResponse.error("请提供日期")

            date = datetime.strptime(date_str, '%Y-%m-%d').date()
            events = self.get_queryset().filter(date=date).values(
                'title', 'start_time', 'end_time', 'importance'
            )

            suggestion = self.ai_service.get_best_time(date, list(events), duration)
            if not suggestion:
                return BaseResponse.error("无法生成时间建议")

            return BaseResponse.success(suggestion)
        except Exception as e:
            return BaseResponse.error(f"获取时间建议失败: {str(e)}")

    @action(detail=True, methods=['post'])
    def share(self, request, pk=None):
        """分享日程给其他用户"""
        try:
            event = self.get_object()
            user_ids = request.data.get('user_ids', [])

            # 使用 related_users 替代 participants
            current_users = set(event.related_users.values_list('id', flat=True))
            new_users = set(user_ids)

            # 添加新用户
            users_to_add = new_users - current_users
            if users_to_add:
                event.related_users.add(*users_to_add)

            return BaseResponse.success({
                'message': '日程分享成功',
                'shared_with': list(users_to_add)
            })
        except Exception as e:
            return BaseResponse.error(f"分享失败: {str(e)}")

    def retrieve(self, request, *args, **kwargs):
        """获取单个日程详情"""
        try:
            instance = self.get_object()
            serializer = self.get_serializer(instance)
            data = serializer.data

            # 如果有关联笔记ID，尝试获取笔记标题
            if instance.related_note_id:
                try:
                    from apps.note.models import Note
                    note = Note.objects.filter(id=instance.related_note_id).first()
                    if note:
                        data['related_note_title'] = note.title
                        # 添加完整的笔记对象，便于前端获取更多信息
                        data['note'] = {
                            'id': note.id,
                            'title': note.title
                        }
                except Exception as e:
                    logger.error(f"获取关联笔记失败: {str(e)}")

            return Response(data)
        except Exception as e:
            logger.error(f"获取日程详情失败: {str(e)}")
            return BaseResponse.error(f"获取日程详情失败: {str(e)}")